home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-04-27 | 6.2 KB | 318 lines | [TEXT/MPS ] |
- #ifndef __DATAAREA__
- #include "DataArea.h"
- #endif
-
- #ifndef __ERRORS__
- #include <errors.h>
- #endif
-
- #ifndef __OSUTILS__
- #include <osutils.h>
- #endif
-
-
- //µ DataArea::DataArea
- #pragma segment DataArea
- DataArea::DataArea()
- : fHandle(0),
- fSize(0),
- fCursor(0),
- fIncrement(0)
- {
- UseHeap(kAppHandleManager);
- }
-
-
- //µ DataArea::IDataArea
- //
- #pragma segment DataArea
- OSErr DataArea::IDataArea(const DataArea *anArea)
- {
- OSErr anErr = noErr;
-
- // Copy all fields
- fHandle = anArea->fHandle;
- fCursor = anArea->fCursor;
- fSize = anArea->fSize;
- fIncrement = anArea->fIncrement;
- fHandleProc = anArea->fHandleProc;
-
- if (fHandle)
- fHandleProc->Duplicate(anArea->fHandle, &fHandle, &anErr);
-
- return (anErr);
- }
-
-
- #pragma segment DataArea
- OSErr DataArea::IDataArea(size_t initialSize, size_t increment, Boolean useSize)
- {
- OSErr anErr;
-
- fHandle = fHandleProc->NewHandle(initialSize, &anErr);
- if (fHandle == 0)
- return (anErr);
-
- fCursor = 0;
- fSize = useSize ? initialSize : 0;
- fIncrement = increment;
-
- return (noErr);
- }
-
-
- //µ DataArea::~DataArea
- //
- #pragma segment DataArea
- DataArea::~DataArea()
- {
- OSErr anErr;
-
- if (fHandle)
- fHandleProc->DisposHandle(fHandle, &anErr);
- }
-
-
- //µ DataArea::Assign
- #pragma segment DataArea
- OSErr DataArea::Assign(const DataArea *anArea)
- {
- // If this is a "virgin" DataArea, use the intializer
- if (fHandle == 0)
- return (IDataArea(anArea));
-
- if (anArea->fHandle != 0) {
- // Assure that there is room for the copy
- size_t amtReqd = anArea->fSize;
-
- fCursor = 0;
- if (Require(amtReqd) < amtReqd)
- return (memFullErr);
- BlockMove((Ptr)anArea->GetData(0), *fHandle, amtReqd);
- }
-
- // Copy all fields
- fCursor = anArea->fCursor;
- fSize = anArea->fSize;
- fIncrement = anArea->fIncrement;
-
- return (noErr);
- }
-
-
- //µ DataArea::Read
- #pragma segment DataArea
- size_t DataArea::Read(const void *aPtr, size_t aLen)
- {
- size_t maxRead = fSize - fCursor;
-
- if (aLen > maxRead)
- aLen = maxRead;
-
- BlockMove(*fHandle, (Ptr)aPtr, (Size)aLen);
- return (aLen);
- }
-
-
- //µ DataArea::Write
- #pragma segment DataArea
- size_t DataArea::Write(void **aHndl)
- {
- OSErr anErr;
- size_t aHndlSize = fHandleProc->GetHandleSize(aHndl, &anErr);
- size_t amtReqd = fCursor + aHndlSize;
-
- if (amtReqd > fSize)
- if (Require(aHndlSize) < aHndlSize)
- return (0);
-
- return (_Write(*aHndl, aHndlSize));
- }
-
-
- #pragma segment DataArea
- size_t DataArea::Write(const void *aPtr, size_t aLen)
- {
- size_t amtReqd = fCursor + aLen;
-
- if (amtReqd > fSize)
- if (Require(aLen) < aLen)
- return (0);
-
- return (_Write(aPtr, aLen));
- }
-
-
- //µ DataArea::DecrCursor
- #pragma segment DataArea
- size_t DataArea::DecrCursor(size_t aDelta)
- {
- if (aDelta > fCursor)
- fCursor = 0;
- else
- fCursor -= aDelta;
-
- return (fCursor);
- }
-
-
- //µ DataArea::SetCursor
- #pragma segment DataArea
- size_t DataArea::SetCursor(size_t aCursor)
- {
- fCursor = (aCursor <= fSize) ? aCursor : fSize;
- return (fCursor);
- }
-
-
- //µ DataArea::Require
- #pragma segment DataArea
- size_t DataArea::Require(size_t amtReqd)
- {
- OSErr anErr;
- size_t sizeReqd = fCursor + amtReqd;
-
- if (sizeReqd > fSize) {
- // Check if the handle is already large enough. If it is, set the
- // size to sizeReqd and return it.
- if (sizeReqd <= fHandleProc->GetHandleSize(fHandle, &anErr)) {
- fSize = sizeReqd;
- return (fSize);
- }
-
- // Expand the existing handle if possible. First expand by the
- // incremental amount if the amount requested is less than the
- // increment. If that fails or if the amount required is greater
- // than the increment, expand by the amount required. If the
- // handle still could not be expanded, create a new handle and
- // copy the data.
- if (amtReqd <= fIncrement)
- fHandleProc->SetHandleSize(fHandle, fCursor + fIncrement, &anErr);
- if (amtReqd > fIncrement || anErr != noErr)
- fHandleProc->SetHandleSize(fHandle, sizeReqd, &anErr);
- if (anErr != noErr) {
- // Oops. Can't do it. Create a new handle and copy data. Again,
- // do it in two steps: first the incremental amount then the minimum
- // amount
- void **aHndl = 0;
-
- if (amtReqd <= fIncrement)
- aHndl = fHandleProc->NewHandle(fCursor + fIncrement, &anErr);
- if (aHndl == 0)
- aHndl = fHandleProc->NewHandle(sizeReqd, &anErr);
-
- if (aHndl == 0)
- return (0);
-
- // BlockMove does not move handles
- BlockMove(*fHandle, *aHndl, fSize);
- fHandleProc->DisposHandle(fHandle, &anErr);
- fHandle = aHndl;
- }
-
- // Update the size of this DataArea's handle
- fSize = sizeReqd;
- }
-
- // Return the amount available.
- return (fSize - fCursor);
- }
-
-
- //µ DataArea::Delete
- #pragma segment DataArea
- void DataArea::Delete(size_t start, size_t end)
- {
- if (fHandle) {
- size_t chunkLength = end - start;
- size_t tailLength = fSize - end;
-
- // Return if out of order or if zero length
- if (start >= end || start > fSize)
- return;
-
- // Adjust fCursor. If before start, it doesn't move. If between
- // start and end, it moves to start. Otherwise, it is beyond end
- // and will be shifted down.
- if (fCursor > start)
- if (fCursor <= end)
- fCursor = start;
- else
- fCursor -= chunkLength;
-
- // Copy the data. fHandle[end .. fSize-1] is copied to fHandle[start]
- BlockMove(GetData(end), GetData(start), (Size)tailLength);
-
- // Adjust the size
- fSize -= chunkLength;
- }
- }
-
-
- //µ DataArea::Truncate
- #pragma segment DataArea
- void DataArea::Truncate()
- {
- OSErr anErr;
-
- if (fHandle)
- fHandleProc->SetHandleSize(fHandle, (fSize = fCursor), &anErr);
- }
-
-
- //µ DataArea::AlignCursor
- #pragma segment DataArea
- size_t DataArea::AlignCursor(size_t alignment)
- {
- size_t extraBytes = alignment - fCursor % alignment;
-
- // Assure the cursor is on an alignment boundary.
- if (extraBytes != alignment)
- if (Require(extraBytes) < extraBytes)
- return (0);
- else
- fCursor += extraBytes;
-
- return (fCursor);
- }
-
-
- //µ DataArea::_Write
- #pragma segment DataArea
- size_t DataArea::_Write(const void *aPtr, size_t aLen)
- {
- BlockMove((Ptr)aPtr, (Ptr)GetData(), (Size)aLen);
- fCursor += aLen;
- return (aLen);
- }
-
-
- //µ DataArea::HLock
- #pragma segment DataArea
- void DataArea::HLock()
- {
- OSErr anErr;
-
- fHandleProc->HLock(fHandle, &anErr);
- }
-
-
- //µ DataArea::HUnlock
- #pragma segment DataArea
- void DataArea::HUnlock()
- {
- OSErr anErr;
-
- fHandleProc->HUnlock(fHandle, &anErr);
- }
-
-
- //µ DataArea::MoveHHi
- #pragma segment DataArea
- void DataArea::MoveHHi()
- {
- OSErr anErr;
-
- fHandleProc->MoveHHi(fHandle, &anErr);
- }
-